from pylons import cache
from pythonblog import model
from pythonblog.model.account import *
from pythonblog.model.content import *
from sqlalchemy.sql import select
import pythonblog.lib.helpers as h

_table = UserProfile.__table__
_column = _table.c

_post_table = Post.__table__
_post_column = _post_table.c

initailized = False
_users_cache = {}  # key: userName, value: UserInfo
_users_cache_2 = {}  # key: id, value: UserInfo
_user_emails = set()

global_cache = cache.get_cache('user.global', type="memory")

class UserInfo(object):

    def get_author(self):
        if self.realName:
            return self.realName
        return self.userName

    author = property(get_author)

    def get_user_logo(self):
        if self.userLogo:
            return self.userLogo
        return '/images/user-logo_default.png'

    user_logo = property(get_user_logo)


def _copy_user(user_info, user):
    user_info.id = user.id
    user_info.userName = user.userName
    user_info.createDate = user.createDate
    user_info.updateDate = user.updateDate
    user_info.loginDate = user.loginDate
    user_info.realName = user.realName
    user_info.gender = user.gender
    user_info.email = user.email
    user_info.city = user.city
    user_info.vocation = user.vocation
    user_info.industry = user.industry
    user_info.userLogo = user.userLogo
    user_info.viewTimes = user.viewTimes

def is_user_exist(userName):
    return _users_cache.has_key(userName)
    """q = meta.Session.query(UserProfile)
    if userName:
        q = q.filter(UserProfile.userName==userName)
    if email:
        q = q.filter(UserProfile.email==email)
    count = q.count()
    if count > 0:
        return True
    return False
    
    """

def is_email_repeat(email, userName=None):
    if not userName:
        return email in _user_emails
    return _users_cache[userName].email != email and email in _user_emails
    """q = meta.Session.query(UserProfile)
    q = q.filter(UserProfile.userName!=userName)
    q = q.filter(UserProfile.email==email)
    count = q.count()
    if count > 0:
        return True
    return False
    
    """

def get_user_by_id(id):
    return _users_cache_2.get(id)

def get_user(userName):
    return _users_cache.get(userName)
    """if _users_cache.has_key(userName):
        return _users_cache[userName]

    user = meta.Session.query(UserProfile).filter(UserProfile.userName==userName).first()
    if user:
        add_to_cache(user)
    return _users_cache.get(userName)
    
    """

def get_top_users():
    return global_cache.get_value(key='top.users',
                                    createfunc=lambda: _query_top_users(),
                                    expiretime=300)

def _query_top_users(limit=30):
    s = select([_column.id, '(user_profile.viewTimes + sum(IFNULL(post.viewTimes,0))) viewTimes'], from_obj=[_table.outerjoin(_post_table)])
    s = s.where(_post_column.status==1)
    s = s.group_by(_column.id)
    s = s.order_by('(user_profile.viewTimes + sum(IFNULL(post.viewTimes,0))) desc')
    s = s.limit(limit)
    return meta.engine.execute(s).fetchall()

def get_user_from_db(id):
    user = meta.Session.query(UserProfile).filter(UserProfile.id==id).first()
    return user

def add_or_update_to_cache(user):
    if not _users_cache.has_key(user.userName):
        _users_cache[user.userName] = UserInfo()
        _users_cache_2[user.id] = _users_cache[user.userName]
        _user_emails.add(user.email)
    else:
        _user_emails.remove(_users_cache[user.userName].email)
        _user_emails.add(user.email)
    _copy_user(_users_cache[user.userName], user)

def add_user_viewTimes(userName):
    meta.engine.execute(_table.update().where(_column.userName==userName).values(viewTimes=_column.viewTimes + 1))
    _users_cache[userName].viewTimes += 1

def update_user_login_date(userName):
    date = h.now()
    meta.engine.execute(_table.update().where(_column.userName==userName).values(loginDate=date))
    _users_cache[userName].loginDate = date

def init_cache():
    global initailized
    if not initailized:
        initailized = True
        users = meta.Session.query(UserProfile).all()
        for user in users:
            add_or_update_to_cache(user)

init_cache()